package com.normal.practise.exceptionHandler;


import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.normal.practise.response.ResponseResult;
import com.normal.practise.utils.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.SystemException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;

import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;
import java.sql.SQLException;


/**
 * @author siyaolee
 * @date 2020/10/26 10:32
 * @describe 全局异常处理
 */

@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    //private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 自定义异常处理方法,使用时需要手动抛出异常
     * throw exception GvSysException
     */
    @ExceptionHandler(GvSysException.class)
    public ResponseResult error(GvSysException e) {
        //log.error(e.getMessage()); // Logback记录异常输出日志信息
        e.printStackTrace();//控制台打印异常
        log.error(ExceptionUtil.getMessage(e));
        return ResponseResult.errorResult(e.getCode(),e.getMsg());
    }
    /**
     * 栈溢出
     *
     * @param e
     * @return
     */
    @ExceptionHandler({StackOverflowError.class})
    public ResponseResult stackOverflowError(StackOverflowError e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "栈溢出");
    }

    /**
     * 400错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    public ResponseResult typeMismatchException(TypeMismatchException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(400, "400错误..TypeMismatchException");
    }

    /**
     * 400错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ResponseResult httpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(400, "400错误..HttpMessageNotReadableException");
    }

    /**
     * 405错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ResponseResult httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(405, "405错误..HttpRequestMethodNotSupportedException");
    }

    /**
     * 406错误
     *
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public ResponseResult httpMediaTypeNotAcceptableException(HttpMediaTypeNotAcceptableException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(405, "406错误..HttpMediaTypeNotAcceptableException");
    }

    /**
     * 空指针异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler({NullPointerException.class})
    public ResponseResult nullPointerException(NullPointerException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "数据为空异常");
    }


    /**
     * 方法的参数错误
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public ResponseResult illegalArgumentException(IllegalArgumentException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "方法参数错误" + e.getLocalizedMessage());
    }

    /**
     * 数组越界异常
     */
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public ResponseResult arrayIndexOutOfBoundsException(ArrayIndexOutOfBoundsException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "数组越界异常。");
    }

    /**
     * 数字运算异常
     */
    @ExceptionHandler({ArithmeticException.class})
    public ResponseResult arithmeticException(ArithmeticException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "数字运算异常。");
    }

    /**
     * 类型不存在异常
     */
    @ExceptionHandler({ClassNotFoundException.class})
    public ResponseResult classNotFoundException(ClassNotFoundException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "指定类型不存在。");
    }

    /**
     * 数据类型转换异常
     */
    @ExceptionHandler({ClassCastException.class})
    public ResponseResult classCastException(ClassCastException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "数据类型转换异常。");
    }

    /**
     * 操作数据库异常
     */
    @ExceptionHandler({SQLException.class})
    public ResponseResult sqlException(SQLException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "操作数据库异常。");
    }

    /**
     * 输入输出异常
     */
    @ExceptionHandler({IOException.class})
    public ResponseResult ioException(IOException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "输入输出异常");
    }

    /**
     * 系统异常
     */
    @ExceptionHandler({SystemException.class})
    public ResponseResult systemException(SystemException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "系统异常");
    }

    /**
     * 捕捉404异常
     */
    @ExceptionHandler({NoHandlerFoundException.class})
    public ResponseResult handle(NoHandlerFoundException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(404, "请求地址错误。");
    }

    /**
     * 无权限
     */
    @ExceptionHandler({IllegalAccessException.class})
    public ResponseResult illegalAccessException(IllegalAccessException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(500, "无操作权限。");
    }

    /**
     * token异常
     */
    @ExceptionHandler({JWTDecodeException.class})
    public ResponseResult jwtDecodeException(JWTDecodeException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(401, "用户登录状态过期，请重新登录!");
    }

    /**
     * token认证异常
     */
    @ExceptionHandler({TokenExpiredException.class})
    public ResponseResult tokenExpiredException(TokenExpiredException e) {
        log.error(e.toString());
        return ResponseResult.errorResult(401, "token验证失败，请重新登录!");
    }

    @ExceptionHandler({HttpMessageConversionException.class})
    public ResponseResult httpMessageConversionException(HttpMessageConversionException e) {
        log.error(e.toString());
        return ResponseResult.errorResult("参数接收异常(缺少参数、参数类型不符合)/无效定义异常。");
    }
}